#include "NetworkPlayer.h"

NetworkPlayer::NetworkPlayer(Hand h, int i, game* g,Server* s):Player(h,i,g,s)
{
	// Local hand and id are used for playing
    localHand=h;
    id=i;
	
	// network_delay causes the net player to pause between requests.
	// This gives the server time to ask the client, and gives the client time to respond.
    network_delay = 50;
	
	// If a message is dropped by the network, the net player will wait for this message to
	// return. The number of times it will check the network to see if the message is there
	// is specified by retry_limit. In seconds this is retry_limit * network_delay / 1000
    retry_limit = 1200;
}

void NetworkPlayer::sendHand()
{
    QString cards = "";

	// Append the cards to a string.
    for(int i=0;i<localHand.getHandSize();i++)
    {
        cards.append(localHand.getCard(i)->suit);
        cards.append(QString::fromStdString(localHand.getCard(i)->num));
        cards.append(",");
    }

	// Wait for server to confirm that the client received the cards.
	while(!server->sendCardArray(id, QString::fromStdString(getUsername()), cards, "own"))
	{
		QThread::msleep(network_delay);
	}
}

QStringList NetworkPlayer::getBid()
{
	// Ask the server to get a bid from the client
    qDebug()<<"Ask "<<QString::fromStdString(getUsername())<<"for bid";
	
    QStringList temp = server->getBid( id, QString::fromStdString(getUsername()));
    int i=0;

	// Wait until the server has a bid to return.
    while(temp.isEmpty())
    {
        QThread::msleep(network_delay);
        temp = server->getBid( id, QString::fromStdString(getUsername()));

        if( i++>retry_limit)
        {
            QStringList err;
            err.append("");
            err.append("");
            err.append("");
            return err;
        }
    }

    return temp;
}

Card NetworkPlayer::getMove(bool a)
{
	// Ask the server to get a move from a client.
	// The boolean value a is either a dummy (true) or non-dummy (false).
    QStringList temp;
    int owner;
    int i=0;

	// 	Wait until the server has a move from the client to return.
    if(!a)
    {
        server->getMove(id, QString::fromStdString(getUsername()));
        while( temp.isEmpty())
        {
            QThread::msleep(network_delay);
            temp = server->getMove(id, QString::fromStdString(getUsername()));

            if( i++>retry_limit)
            {
                return Card('a',0,0,0);
            }
        }
        owner = temp.at(2).toInt();
    }
    else
    {
        temp = server->getDummyMove(id, QString::fromStdString(getUsername()));
        while( temp.isEmpty())
        {
            QThread::msleep(network_delay);
            temp = server->getDummyMove(id, QString::fromStdString(getUsername()));

            if( i++>retry_limit)
            {
                return Card('a',0,0,0);
            }
        }
        owner = partner->id;
    }

    string tSuit=temp.at(0).toUtf8().constData();
    char suit=tSuit[0];

    string num = temp.at(1).toUtf8().constData();

    return Card(suit,0,owner,num);
}

void NetworkPlayer::sendBid(QStringList bid, int)
{
	// Wait for server to confirm that the client received the bid.
	while(!server->sendBid(id,QString::fromStdString(getUsername()),bid.at(3), bid.at(0), bid.at(1), bid.at(2)))
	{
		QThread::msleep(network_delay);
	}
}

void NetworkPlayer::sendMove(Card card, QString)
{
    QString suit="";
    suit.append(card.suit);

	// Wait for server to confirm that the client received a move.
    while(!server->sendMove(QString::fromStdString(getUsername()), card.owner, suit,QString::fromStdString(card.num)))
    {
        QThread::msleep(network_delay);
    }
}

void NetworkPlayer::moveInvalid()
{
    //sendACknowlage(0,5);
}

void NetworkPlayer::bidInvalid()
{
    //sendACknowlage(int id,0,2);
     qDebug()<<QString::fromStdString(getUsername())<<"bid invalid";
}

void NetworkPlayer::startDealing()
{
	// Wait for server to confirm that the client received the start dealing message.
    while(!server->sendPhase(id, QString::fromStdString(getUsername()), QString("dealing")))
    {
        QThread::msleep(network_delay);
    }
}

void NetworkPlayer::startRedealing()
{
	// Wait for server to confirm that the client received the start redealing message.
	server->sendPhase(id,QString::fromStdString(getUsername()), "redealing");
}

void NetworkPlayer::startBidding()
{
	// Wait for server to confirm that the client received the start bidding message.
    while(!server->sendPhase(id, QString::fromStdString(getUsername()), "bidding"))
    {
        QThread::msleep(network_delay);
    }
}

void NetworkPlayer::startPlay()
{
	// Wait for server to confirm that the client received the start play message.
    while( !server->sendPhase(id,QString::fromStdString(getUsername()), "play"))
    {
        QThread::msleep(network_delay);
    }
}

void NetworkPlayer::RubberDone()
{
    //  sendPhase(int id, "Rubber Done")
    server->sendPhase(id,QString::fromStdString(getUsername()), "rubber_done");
}

void NetworkPlayer::sendTrickWinner(QString team, QString player)
{
	// Wait for server to confirm that the client received the send trick winner message.
    while( !server->sendWonUpdate(QString::fromStdString(getUsername()), team, player, "won_trick"))
    {
        QThread::msleep(network_delay);
    }
}

void NetworkPlayer::sendContract(QStringList cont)
{
	// Wait for server to confirm that the client received the send contract message.
    while( !server->sendContract(QString::fromStdString(getUsername()), cont.at(1).toInt(), cont.at(2)))
    {
        QThread::msleep(network_delay);
    }
}

void NetworkPlayer::sendDummyId(string dummy)
{
	// Wait for server to confirm that the client received the send dummy id message.
    while( !server->sendDummyID( id, QString::fromStdString(getUsername()),QString::fromStdString(dummy)))
    {
        QThread::msleep(network_delay);
    }
}

void NetworkPlayer::sendDummyCards(Hand dummyHand)
{
    QString cards="";

	// Append the dummy's cards to a string
    for(int i=0;i<dummyHand.getHandSize();i++)
    {
        cards.append(dummyHand.getCard(i)->suit);
        cards.append(QString::fromStdString(dummyHand.getCard(i)->num));
        cards.append(",");
    }

	// Wait for server to confirm that the client received the dummy's cards.
    while(!server->sendCardArray(id, QString::fromStdString(getUsername()), cards, "dummy"))
    {
        QThread::msleep(network_delay);
    }
}

void NetworkPlayer::updateScore(QString wa, QString wb, QString ta, QString tb)
{
	// Wait for server to confirm that the client received the update score message.
    while( !server->scoreUpdate( QString::fromStdString(getUsername()), wa, wb, ta, tb))
    {
        QThread::msleep(network_delay);
    }
}

void NetworkPlayer::sendRubberWinner(QString team)
{
	// Wait for server to confirm that the client received the send rubber winner message.
     while( !server->sendWonUpdate(QString::fromStdString(getUsername()),team,"","won_rubber"))
     {
         QThread::msleep(network_delay);
     }
}

void NetworkPlayer::sendGameWinner(QString team)
{
	// Wait for server to confirm that the client received the send won update message.
      while( !server->sendWonUpdate(QString::fromStdString(getUsername()),team,"","won game"))
      {
          QThread::msleep(network_delay);
      }
}

void  NetworkPlayer::sendGameStatus(QStringList game)
{
	// Wait for server to confirm that the client received the send game status message.
    while( !server->sendGameStatus( QString::fromStdString(getUsername()), game))
    {
        QThread::msleep(network_delay);
    }
}
